package cn.sunxyz.methodinference.parser;

import cn.sunxyz.methodinference.rule.SQLKeywords;
import cn.sunxyz.methodinference.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by yangrd on 2017/5/28.
 */
public abstract class AbstractSQLParser implements SQLParser {

    private static final Logger logger = LoggerFactory.getLogger(AbstractSQLParser.class);

    @Override
    public String parser(String input) {
        return parser(extract(segmentation(input)));//TODO 需要去掉查询前缀 调用##extract()与##parser()
    }


    /**
     * 将extractList解析(翻译)成sql
     */
    public abstract String parser(List<Object> extractList);

    /**
     * 根据大写字母进行分割 如 NameAndAgeOrAddress to [Name,And,Age,Or,Address]
     */
    protected List<String> segmentation(String input) {
        return StringUtil.camelToList(input);
    }

    /**
     * 负责提取sql关键字及属性 [Name,And,Age,Or,Address] to [Name,AND,Age,OR,Address]
     */
    protected List<Object> extract(List<String> list) {
        List<Object> extractList = new ArrayList<>();
        List<String> cupList = list;
        int len = cupList.size();
        int step = 0;
        int lastStep = len;
        while (step < len) {
            if (lastStep <= step) {
                step++;
                lastStep = len;
            }
            String key = subListToString(cupList, step, lastStep);
            if (SQLKeywords.isPresent(key)) {
                if (step > 0) {
                    String prop = subListToString(cupList, 0, step);
                    logger.debug("prop==> {} ", prop);
                    extractList.add(prop);
                }
                SQLKeywords.Keywords keywords = SQLKeywords.getKeywords(key);
                extractList.add(keywords);
                logger.debug("keywords==> {} ", keywords);
                //初始化杯子
                cupList = cupList.subList(lastStep, len);
                len = cupList.size();
                step = 0;
                lastStep = len;
            }
            lastStep--;
        }
        if (len > 0) {
            String prop = subListToString(cupList, 0, len);
            logger.debug("prop==> {} ", prop);
            extractList.add(prop);
        }
        return extractList;
    }

    protected String subListToString(List<String> list, int fromIndex, int toIndex) {
        return list.subList(fromIndex, toIndex).stream().collect(Collectors.joining());
    }

}
